<?php
namespace App\Common\Lib\Api;

use App\Common as com;
use App\Common\Lib\Api\Exception as thisException;
use App\Common\Lib\Api as nameApi;

class Exception extends com\Lib\LibBase {

	private \Throwable $e;

	public function __construct( \Throwable $e ) {
		$this->e = $e;
		//
		parent::__construct();
	}

	/**
	 * api异常处理
	 * @return nameApi\Response
	 */
	public function toApiResponse(  ) {
		//
		$apiResponse = nameApi\Response::make();
		//
		// 异常转错误响应
		if( is_numeric( $this->e->getCode() ) ){
			$showCode = $this->e->getCode() > 0 ? 0 : $this->e->getCode(); // 不允许大于0
		}else{
			$showCode = 0;
		}
		$showMessage = $this->e->getMessage();
		if( $this->e->getCode() > 0 ){
			$showMessage = "[" . $this->e->getCode() . "]" . $showMessage;
		}
		$apiResponse->setCodeAndMsg( $showCode, $showMessage );
		// 特殊错误->外部调用错误
		if( $this->e instanceof com\Lib\Err\Exception\ExtExternal ){
			// 输出外部错误信息
			$apiResponse->addExtendedData( [
				'externalInfo' => $this->e->getExternalInfo(),
			] );
		}
		//
		// 是否输出具体的错误文件地址
		$apiDebugInfoConfig = config('api.debugInfo');
		if( $apiDebugInfoConfig['isDebugMode'] == true && $apiDebugInfoConfig['showDebugToApi'] == true ){
			$apiResponse->addExtendedData( [
				'debug' => $this->buildDebugInfo( $this->e, $apiDebugInfoConfig['showInfo']['traceField'] ?? null ),
			] );
		}
		//
		return $apiResponse;
	}

	private function buildDebugInfo( \Throwable $e, $configShowInfoTraceField = null ) {
		$debugInfo = [];
		$debugInfo['errFile'] = $e->getFile() . '[' . $e->getLine() . '] ' .  $e->getMessage();
		$debugInfo['courseData'] = com\Lib\Err\GetBack::getCourseData( );
		$debugInfo['trace'] = [];
		$trace = $e->getTrace();
		$traceCount = count( $trace );
		$maxShowTraceNum = 100;
		for( $index = 0; $index < $maxShowTraceNum && $index < $traceCount - 1; $index++ ){
			//
			$extendedItem = [];
			if( $configShowInfoTraceField == 'all' ){
				$extendedItem = $trace[ $index ];
			}else if( is_array( $configShowInfoTraceField ) ){
				foreach( $configShowInfoTraceField as $traceFieldValue  ){
					if( isset( $trace[ $index ][ $traceFieldValue ] ) ){
						$extendedItem[ $traceFieldValue ] = $trace[ $index ][ $traceFieldValue ];
					}
				}
			}
			//
			$debugInfo['trace'][] = $extendedItem;
		}
		// 超过最大显示数量提示
		if( $traceCount > $maxShowTraceNum ){
			$debugInfo['trace'][] = 'The maximum display amount is exceeded';
		}
		//
		return $debugInfo;
	}

	// ===============================
	//
	//
	// 下面为静态方法
	//
	//
	// ===============================

	public static function new( \Throwable $e ):self {
		return new static( $e );
	}

}
